﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity.Infrastructure;
using System.Linq;

namespace SalesCore.Data.Entity
{
    public interface IDataProviderFactory
    {
        DbConnection CreateConnection(string dataConnectionString);

        void CreateTables(string script, Action<string> executeSqlCommand, Func<string, Type, IEnumerable> executeSqlQuery);
    }

    public class SqlServerDataProviderFactory : IDataProviderFactory
    {
        public DbConnection CreateConnection(string connectionString)
        {
            return new SqlConnectionFactory().CreateConnection(connectionString);
        }

        public void CreateTables(string script, Action<string> executeSqlCommand, Func<string, Type, IEnumerable> executeSqlQuery)
        {
            List<string> existingTableNames;
            try
            {
                existingTableNames = new List<string>();
                var tables = executeSqlQuery("SELECT table_name from INFORMATION_SCHEMA.TABLES WHERE table_type = 'base table'", typeof(string));
                var tablesEnumerator = tables.GetEnumerator();

                while (tablesEnumerator.MoveNext())
                {
                    existingTableNames.Add(Convert.ToString(tablesEnumerator.Current));
                }
            }
            catch (Exception)
            {
                existingTableNames = new List<string>();
            }

            var split = script.Split(new[] { "create table " }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var sql in split)
            {
                var tableName = sql.Substring(0, sql.IndexOf("(", StringComparison.Ordinal));
                tableName = tableName.Split('.').Last();
                tableName = tableName.Trim().TrimStart('[').TrimEnd(']');

                if (existingTableNames.Contains(tableName))
                {
                    continue;
                }

                try
                {
                    executeSqlCommand("CREATE TABLE" + sql);
                }
                catch (DbException)
                {
                    // Ignore when existing
                }
            }
        }
    }
}